package com.pingao.mp.modular.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pingao.mp.modular.sys.entity.Menu;
import com.pingao.mp.modular.sys.entity.Permission;
import com.pingao.mp.modular.sys.entity.Role;
import com.pingao.mp.modular.sys.mapper.MenuMapper;
import com.pingao.mp.modular.sys.mapper.PermissionMapper;
import com.pingao.mp.modular.sys.service.MenuService;
import com.pingao.mp.modular.sys.service.UserService;
import com.pingao.mp.utils.Constant;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 菜单表  服务实现类
 * </p>
 *
 * @author 闻品高
 * @since 2018-09-26
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private UserService userService;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Override
    public List<Menu> getLoginMenu(){
        List<Menu> loginUserMenus = new ArrayList<>();
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        Object loginUserMenusObj = session.getAttribute(Constant.LoginUserMenus);
        if(loginUserMenusObj != null){
            loginUserMenus = (List<Menu>) loginUserMenusObj;
            return loginUserMenus;
        }
        String username = (String) session.getAttribute(Constant.LoginUserName);
        if(username == null){
            username = currentUser.getPrincipal().toString();
            session.setAttribute(Constant.LoginUserName,username);
        }
        Set<Role> roles = userService.getRolesByUsername(username);
        if(roles == null || roles.size() < 1){
            return loginUserMenus;
        }
        List<Integer> roleIds = new ArrayList<>();
        roles.forEach(role -> roleIds.add(role.getId()));

        List<Permission> permissions = permissionMapper.selectList(new QueryWrapper<Permission>().in(Permission.COL_ROLE_ID,roleIds).isNull(Permission.COL_DELETE_TIME).select(Permission.COL_MENU_ID));
        if (permissions == null || permissions.size() < 1){
            return loginUserMenus;
        }
        Set<Integer> menus = new HashSet<>();
        permissions.forEach(permission->menus.add(permission.getMenuId()));
        loginUserMenus = list(new QueryWrapper<Menu>().in(Menu.COL_ID,menus).isNull(Menu.COL_DELETE_TIME).eq(Menu.COL_IS_MENU,1).orderByAsc(Menu.COL_SORT));
        for (Menu menu : loginUserMenus) {
            String url = "";
            if(menu.getModuleName() != null && menu.getModuleName().length() > 0){
                url += "/" + menu.getModuleName();
            }
            if(menu.getActionName() != null && menu.getActionName().length() > 0){
                url += "/" + menu.getActionName();
            }
            if(menu.getFunctionName() != null && menu.getFunctionName().length() > 0){
                url += "/" + menu.getFunctionName();
            }
            menu.setUrl(url);
        }
        session.setAttribute(Constant.LoginUserMenus,loginUserMenus);
        return loginUserMenus;
    }

    @Override
    public List<Menu> getList(String search) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("1","1");
        if(search != null && !"".equals(search)){
            wrapper.and(q->q.like(Menu.COL_NAME,search).or().like(Menu.COL_MODULE_NAME,search).or().like(Menu.COL_ACTION_NAME,search).or().like(Menu.COL_FUNCTION_NAME,search));
        }
//        wrapper.orderByDesc("update_time");
        wrapper.orderByAsc(Menu.COL_SORT);
        return list(wrapper);
    }

    @Override
    public List<Menu> getMenuTree(Integer id) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        if(id == null){
            wrapper.eq(Menu.COL_PARENT_ID,0);
        }else{
            wrapper.eq(Menu.COL_PARENT_ID,id);
        }
        List<Menu> menus = list(wrapper);

        for (Menu menu : menus) {
            int c = count(new QueryWrapper<Menu>().eq(Menu.COL_PARENT_ID,menu.getId()));
            menu.setHasChild(c > 0);
        }

        return menus;
    }

    @Override
    public void deleteMenuById(Integer s) {
        TransactionStatus transactionStatus = null;
        try{
            transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            //删除菜单
            //删除权限表中菜单的所有数据
            QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
            permissionQueryWrapper.eq(Permission.COL_MENU_ID,s);
            permissionMapper.delete(permissionQueryWrapper);
            removeById(s);
            dataSourceTransactionManager.commit(transactionStatus);
        }catch (Exception e){
            if (transactionStatus != null){
                dataSourceTransactionManager.rollback(transactionStatus);
            }
            throw e;
        }

    }
}
